{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### In order to make our gunshots dataset large we gathered gunshots audios from different datasets.Following code is writtrn to extract gunshot audios from MIVIA dataset. In this dataset there were three categories of audios (gunshot, glass break and screams) embedde in a single audio. Timing information for each audio was provided in xml file such that each class category start and end time was given in xml file. So gun shots were extracted from each audio using xml file timing information."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### importing libraries"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import xml.etree.ElementTree as ET\n",
    "import sys\n",
    "import numpy as np\n",
    "import wave\n",
    "import pyaudio\n",
    "import struct\n",
    "import math\n",
    "import os"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### complete code for gunshot,scream,glass break,background audio extraction from single audio of MIVIA dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#this training audio path can be changed to testing for extracting testing audios\n",
    "#MIVIA DATASET Training sound path\n",
    "File=\"E:\\\\All Data\\\\study\\\\MS\\\\2\\\\machine learning\\\\Project\\\\MIVIA_dataset\\\\MIVIA_DB4_dist\\\\training\\\\sounds\"    \n",
    "#MIVIA DATASET Training xml path\n",
    "path=\"E:\\\\All Data\\\\study\\\\MS\\\\2\\\\machine learning\\\\Project\\\\MIVIA_dataset\\\\MIVIA_DB4_dist\\\\training\"\n",
    "folder=path\n",
    "#loop over entire xml files\n",
    "for xml in os.listdir(path):  \n",
    "    #check if xml\n",
    "    if xml.split('.')[-1]==\"xml\":\n",
    "        #load xml file\n",
    "       tree = ET.parse(path+\"\\\\\"+xml)\n",
    "       #get root of xml file\n",
    "       root = tree.getroot()\n",
    "       #initialize counters for naming\n",
    "       glass=0\n",
    "       gun=0\n",
    "       scream=0\n",
    "       back=0\n",
    "    else:\n",
    "        continue\n",
    "#loop over xml root->child         \n",
    "    for i in root:\n",
    "        for j in i:\n",
    "            for k in j:\n",
    "                #get the audio class name\n",
    "                if k.tag==\"CLASS_NAME\":\n",
    "                    name=k.text.split(\"/\")[0]\n",
    "                #get start second of that audio class from xml and round the value to floor   \n",
    "                if k.tag==\"STARTSECOND\":\n",
    "                    start = int(math.floor(float(k.text.split(\"/\")[0])))\n",
    "                #get end second of that audio class from xml and round the value to ceil\n",
    "                if k.tag==\"ENDSECOND\":\n",
    "                    end = int(math.ceil(float(k.text.split(\"/\")[0])))\n",
    "            #check if folder with specific class name exists or not if not then create\n",
    "            if os.path.isdir(folder+\"\\\\\"+\"train_\"+name):\n",
    "                pass\n",
    "            else:\n",
    "                #os.rmdir(folder+\"\\\\\"+name)\n",
    "                os.mkdir(folder+\"\\\\\"+\"train_\"+name)\n",
    "            print (start,end,name)\n",
    "            #print store\n",
    "            length =end-start\n",
    "            #loop over MIVIA sound folder and get the storing audio class path\n",
    "            for audio in os.listdir(File):\n",
    "                chunk = 1024\n",
    "                #check if audio name matches xml to be processed \n",
    "                if audio.split('.')[0].split('_')[0]==xml.split('.')[0]:\n",
    "                    #check the class name of audio section to be extracted and give storing path acordingly\n",
    "                    if name==\"glass\":\n",
    "                        store=folder+\"\\\\\"+\"train_\"+name+\"\\\\\"+name+str(glass)+\"_\"+audio.split('.')[0]+\".wav\"\n",
    "                        glass=glass+1\n",
    "                    if name==\"gunshots\":\n",
    "                        store=folder+\"\\\\\"+\"train_\"+name+\"\\\\\"+name+str(gun)+\"_\"+audio.split('.')[0]+\".wav\"\n",
    "                        gun=gun+1\n",
    "                    if name==\"screams\":\n",
    "                        store=folder+\"\\\\\"+\"train_\"+name+\"\\\\\"+name+str(scream)+\"_\"+audio.split('.')[0]+\".wav\"\n",
    "                        scream=scream+1\n",
    "                    if name==\"background\":\n",
    "                        store=folder+\"\\\\\"+\"train_\"+name+\"\\\\\"+name+str(back)+\"_\"+audio.split('.')[0]+\".wav\"\n",
    "                        back=back+1\n",
    "                    #open audio file\n",
    "                    spf = wave.open(File+\"\\\\\"+audio, 'rb')\n",
    "                    signal = spf.readframes(-1)\n",
    "                    #frame=signal\n",
    "                    signal = np.fromstring(signal, 'Int16')\n",
    "                    p = pyaudio.PyAudio()\n",
    "                    stream = p.open(format =\n",
    "                                    p.get_format_from_width(spf.getsampwidth()),\n",
    "                                    channels = spf.getnchannels(),\n",
    "                                    rate = spf.getframerate(),\n",
    "                                    output = True)\n",
    "                    #extract the audio of specific length of specific class{glass break,gunshot,background or scream} provided in xml \n",
    "                    pos=spf.getframerate()*length\n",
    "                    signal =signal[start*spf.getframerate():(start*spf.getframerate()) + pos]\n",
    "                    sig=signal[1:chunk]\n",
    "                    inc = 0;\n",
    "                    data=0;\n",
    "                    frame=[]\n",
    "                    #get the audio extracted data again to be stored\n",
    "                    while data != '':\n",
    "                        data = struct.pack(\"%dh\"%(len(sig)), *list(sig))\n",
    "                        frame.append(data)\n",
    "                        #stream.write(data)\n",
    "                        inc=inc+chunk\n",
    "                        sig=signal[inc:inc+chunk]\n",
    "                    stream.close()\n",
    "                    p.terminate()\n",
    "                    wf = wave.open(store, 'wb') \n",
    "                    wf.setnchannels(spf.getnchannels())\n",
    "                    #print (spf.getnchannels())\n",
    "                    wf.setsampwidth(p.get_sample_size(pyaudio.paInt16))\n",
    "                    #print (spf.getframerate())\n",
    "                    wf.setframerate(spf.getframerate())\n",
    "                    wf.writeframes(b''.join(frame))# store the extracted audio\n",
    "                    wf.close()\n",
    "                else:\n",
    "                    pass\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.14"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
